#include "widget_node_transform.h"
#include "ui_widget_node_transform.h"
#include <QDoubleValidator>
#include "../Program.h"
#include "../AvatarLibrary.h"

WidgetNodeTransform::WidgetNodeTransform(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::WidgetNodeTransform)
{
    ui->setupUi(this);
    QDoubleValidator* val = new QDoubleValidator(this);
    val->setDecimals(6);
    val->setNotation(QDoubleValidator::StandardNotation);
    ui->lineEditPosX->setValidator(val);
    ui->lineEditPosY->setValidator(val);
    ui->lineEditPosZ->setValidator(val);
    ui->lineEditRotX->setValidator(val);
    ui->lineEditRotY->setValidator(val);
    ui->lineEditRotZ->setValidator(val);
    ui->lineEditScaleX->setValidator(val);
    ui->lineEditScaleY->setValidator(val);
    ui->lineEditScaleZ->setValidator(val);
    connect(ui->lineEditPosX, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(ui->lineEditPosY, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(ui->lineEditPosZ, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(ui->lineEditRotX, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(ui->lineEditRotY, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(ui->lineEditRotZ, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(ui->lineEditScaleX, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(ui->lineEditScaleY, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(ui->lineEditScaleZ, &QLineEdit::returnPressed, this, &WidgetNodeTransform::lineEdit_returnPressed);
    connect(qApp, &QApplication::focusChanged, this, &WidgetNodeTransform::lineEdit_focusChanged);
    _currentNode = nullptr;
}

WidgetNodeTransform::~WidgetNodeTransform()
{
    delete ui;
}

/**
 * @brief 设置变换节点
 * @param name
 */
void WidgetNodeTransform::setupNode(const QString &name)
{
    _currentNode = Program::SceneNodeList[name];
    ui->lineEditPosX->setText(QString::number(_currentNode->Position.x()));
    ui->lineEditPosY->setText(QString::number(_currentNode->Position.y()));
    ui->lineEditPosZ->setText(QString::number(_currentNode->Position.z()));
    ui->lineEditRotX->setText(QString::number(_currentNode->Angle.x()));
    ui->lineEditRotY->setText(QString::number(_currentNode->Angle.y()));
    ui->lineEditRotZ->setText(QString::number(_currentNode->Angle.z()));
    ui->lineEditScaleX->setText(QString::number(_currentNode->Scale.x()));
    ui->lineEditScaleY->setText(QString::number(_currentNode->Scale.y()));
    ui->lineEditScaleZ->setText(QString::number(_currentNode->Scale.z()));
    AvatarLibrary::avatar_command("scene.delete('__gizmo')");
    AvatarLibrary::avatar_command(QString("scene.insert('%1', 'gizmo', '__gizmo')").arg(_currentNode->Name));
    AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetKeySwitch', {enable=true})");
    AvatarLibrary::avatar_register("__GetTransform", handleTransform, this);
}

void WidgetNodeTransform::hideEvent(QHideEvent *event)
{
    AvatarLibrary::avatar_command("scene.delete('__gizmo')");
}

void WidgetNodeTransform::lineEdit_returnPressed()
{
    QLineEdit* lineEdit = qobject_cast<QLineEdit*>(sender());
    if (_currentNode)
    {
        const QString format = QString("scene.%2('%1',%3,%4,%5)").arg(_currentNode->Name);
        if (lineEdit == ui->lineEditPosX || lineEdit == ui->lineEditPosY || lineEdit == ui->lineEditPosZ)
        {
            _currentNode->Position.setX(ui->lineEditPosX->text().toFloat());
            _currentNode->Position.setY(ui->lineEditPosY->text().toFloat());
            _currentNode->Position.setZ(ui->lineEditPosZ->text().toFloat());
            AvatarLibrary::avatar_command(format.arg("position", ui->lineEditPosX->text(), ui->lineEditPosY->text(), ui->lineEditPosZ->text()));
            AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='translate'})");
            AvatarLibrary::avatar_command(QString("setCameraTarget('%1')").arg(_currentNode->Name));
        }
        if (lineEdit == ui->lineEditRotX || lineEdit == ui->lineEditRotY || lineEdit == ui->lineEditRotZ)
        {
            _currentNode->Angle.setX(ui->lineEditRotX->text().toFloat());
            _currentNode->Angle.setY(ui->lineEditRotY->text().toFloat());
            _currentNode->Angle.setZ(ui->lineEditRotZ->text().toFloat());
            AvatarLibrary::avatar_command(format.arg("angle", ui->lineEditRotX->text(), ui->lineEditRotY->text(), ui->lineEditRotZ->text()));
            AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='rotate'})");
        }
        if (lineEdit == ui->lineEditScaleX || lineEdit == ui->lineEditScaleY || lineEdit == ui->lineEditScaleZ)
        {
            _currentNode->Scale.setX(ui->lineEditScaleX->text().toFloat());
            _currentNode->Scale.setY(ui->lineEditScaleY->text().toFloat());
            _currentNode->Scale.setZ(ui->lineEditScaleZ->text().toFloat());
            AvatarLibrary::avatar_command(format.arg("scale", ui->lineEditScaleX->text(), ui->lineEditScaleY->text(), ui->lineEditScaleZ->text()));
            AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='scale'})");
        }
    }
}

void WidgetNodeTransform::lineEdit_focusChanged(QWidget *old, QWidget *now)
{
    if (now == ui->lineEditPosX || now == ui->lineEditPosY || now == ui->lineEditPosZ) AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='translate'})");
    else if (now == ui->lineEditRotX || now == ui->lineEditRotY || now == ui->lineEditRotZ) AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='rotate'})");
    else if (now == ui->lineEditScaleX || now == ui->lineEditScaleY || now == ui->lineEditScaleZ) AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='scale'})");
}

void WidgetNodeTransform::on_pushButtonReset_clicked()
{
    if (_currentNode)
    {
        _currentNode->Position.setX(0.0f);
        _currentNode->Position.setY(0.0f);
        _currentNode->Position.setZ(0.0f);
        _currentNode->Angle.setX(0.0f);
        _currentNode->Angle.setY(0.0f);
        _currentNode->Angle.setZ(0.0f);
        _currentNode->Scale.setX(1.0f);
        _currentNode->Scale.setY(1.0f);
        _currentNode->Scale.setZ(1.0f);
        ui->lineEditPosX->setText("0");
        ui->lineEditPosY->setText("0");
        ui->lineEditPosZ->setText("0");
        ui->lineEditRotX->setText("0");
        ui->lineEditRotY->setText("0");
        ui->lineEditRotZ->setText("0");
        ui->lineEditScaleX->setText("1");
        ui->lineEditScaleY->setText("1");
        ui->lineEditScaleZ->setText("1");
        AvatarLibrary::avatar_command(QString("scene.position('%1',%2)").arg(_currentNode->Name, _currentNode->Position.ToString()));
        AvatarLibrary::avatar_command(QString("scene.angle('%1',%2)").arg(_currentNode->Name, _currentNode->Angle.ToString()));
        AvatarLibrary::avatar_command(QString("scene.scale('%1',%2)").arg(_currentNode->Name, _currentNode->Scale.ToString()));
        AvatarLibrary::avatar_command(QString("setCameraTarget('%1')").arg(_currentNode->Name));
    }
}

void WidgetNodeTransform::on_pushButtonApply_clicked()
{
    if (_currentNode)
    {
        _currentNode->Position.setX(ui->lineEditPosX->text().toFloat());
        _currentNode->Position.setY(ui->lineEditPosY->text().toFloat());
        _currentNode->Position.setZ(ui->lineEditPosZ->text().toFloat());
        _currentNode->Angle.setX(ui->lineEditRotX->text().toFloat());
        _currentNode->Angle.setY(ui->lineEditRotY->text().toFloat());
        _currentNode->Angle.setZ(ui->lineEditRotZ->text().toFloat());
        _currentNode->Scale.setX(ui->lineEditScaleX->text().toFloat());
        _currentNode->Scale.setY(ui->lineEditScaleY->text().toFloat());
        _currentNode->Scale.setZ(ui->lineEditScaleZ->text().toFloat());
        AvatarLibrary::avatar_command(QString("scene.position('%1',%2)").arg(_currentNode->Name, _currentNode->Position.ToString()));
        AvatarLibrary::avatar_command(QString("scene.angle('%1',%2)").arg(_currentNode->Name, _currentNode->Angle.ToString()));
        AvatarLibrary::avatar_command(QString("scene.scale('%1',%2)").arg(_currentNode->Name, _currentNode->Scale.ToString()));
        AvatarLibrary::avatar_command("scene.delete('__gizmo')");
    }
}

void WidgetNodeTransform::on_pushButtonResetPos_clicked()
{
    if (_currentNode)
    {
        _currentNode->Position.setX(0.0f);
        _currentNode->Position.setY(0.0f);
        _currentNode->Position.setZ(0.0f);
        ui->lineEditPosX->setText("0");
        ui->lineEditPosY->setText("0");
        ui->lineEditPosZ->setText("0");
        AvatarLibrary::avatar_command(QString("scene.position('%1',%2)").arg(_currentNode->Name, _currentNode->Position.ToString()));
        AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='translate'})");
        AvatarLibrary::avatar_command(QString("setCameraTarget('%1')").arg(_currentNode->Name));
    }
}

void WidgetNodeTransform::on_pushButtonResetRot_clicked()
{
    if (_currentNode)
    {
        _currentNode->Angle.setX(0.0f);
        _currentNode->Angle.setY(0.0f);
        _currentNode->Angle.setZ(0.0f);
        ui->lineEditRotX->setText("0");
        ui->lineEditRotY->setText("0");
        ui->lineEditRotZ->setText("0");
        AvatarLibrary::avatar_command(QString("scene.angle('%1',%2)").arg(_currentNode->Name, _currentNode->Angle.ToString()));
        AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='rotate'})");
    }
}

void WidgetNodeTransform::on_pushButtonResetScale_clicked()
{
    if (_currentNode)
    {
        _currentNode->Scale.setX(1.0f);
        _currentNode->Scale.setY(1.0f);
        _currentNode->Scale.setZ(1.0f);
        ui->lineEditScaleX->setText("1");
        ui->lineEditScaleY->setText("1");
        ui->lineEditScaleZ->setText("1");
        AvatarLibrary::avatar_command(QString("scene.scale('%1',%2)").arg(_currentNode->Name, _currentNode->Scale.ToString()));
        AvatarLibrary::avatar_command("scene.handle('__gizmo', 'SetMode', {mode='scale'})");
    }
}

int WidgetNodeTransform::handleTransform(int, const char** transform, void* form)
{
    WidgetNodeTransform* widgetNodeTransform = static_cast<WidgetNodeTransform*>(form);
    if (widgetNodeTransform->_currentNode)
    {
        EntitySceneNode* node = widgetNodeTransform->_currentNode.get();
        node->Position.setX(strtof(transform[0], 0));
        node->Position.setY(strtof(transform[1], 0));
        node->Position.setZ(strtof(transform[2], 0));
        node->Angle.setX(strtof(transform[3], 0));
        node->Angle.setY(strtof(transform[4], 0));
        node->Angle.setZ(strtof(transform[5], 0));
        node->Scale.setX(strtof(transform[6], 0));
        node->Scale.setY(strtof(transform[7], 0));
        node->Scale.setZ(strtof(transform[8], 0));
        widgetNodeTransform->ui->lineEditPosX->setText(QString::number(node->Position.x()));
        widgetNodeTransform->ui->lineEditPosY->setText(QString::number(node->Position.y()));
        widgetNodeTransform->ui->lineEditPosZ->setText(QString::number(node->Position.z()));
        widgetNodeTransform->ui->lineEditRotX->setText(QString::number(node->Angle.x()));
        widgetNodeTransform->ui->lineEditRotY->setText(QString::number(node->Angle.y()));
        widgetNodeTransform->ui->lineEditRotZ->setText(QString::number(node->Angle.z()));
        widgetNodeTransform->ui->lineEditScaleX->setText(QString::number(node->Scale.x()));
        widgetNodeTransform->ui->lineEditScaleY->setText(QString::number(node->Scale.y()));
        widgetNodeTransform->ui->lineEditScaleZ->setText(QString::number(node->Scale.z()));
    }
    return 0;
}
